﻿
Imports std
Imports storoomc

Public Interface stornodebase
    Inherits comparableStorageInterface(Of stornodebase), IDisplay, storageInterface
End Interface

Public Module _stornodebase
    Public Function _compare(ByVal this As nodes_redundance2, ByVal other As nodes_redundance2) As Int32
        If this Is Nothing AndAlso other Is Nothing Then
            Return 0
        ElseIf this Is Nothing Then
            Return -1
        ElseIf other Is Nothing Then
            Return 1
        Else
            Return compare(this.slices, other.slices)
        End If
    End Function

    Public Sub _new(ByVal this As nodes_redundance2, ByVal inputhost As String, ByVal inputport As String)
        assert(Not this Is Nothing)
        'use set to dedup, nodes_redundance2 is not order-sensitive
        Dim addresses As [set](Of pair(Of String, Int32)) = Nothing
        addresses = New [set](Of pair(Of String, Int32))()

        Dim hosts As vector(Of String) = Nothing
        strsepar(inputhost, character.comma, hosts, True)
        Dim ports As vector(Of String) = Nothing
        strsepar(inputport, character.comma, ports, True)
        If hosts.size() <> ports.size() AndAlso ports.size() > 1 Then
            raiseError("inputhost list size <> inputport list size, use the first port.", errorHandle.errorType.warning)
        End If
        Dim i As Int64
        For i = 0 To hosts.size() - 1
            Dim port As Int32
            Dim portStr As String = Nothing
            portStr = ifoper(hosts.size() <> ports.size(), ports(0), ports(i))
            If Not convertor.toint32(portStr, port) Then
                raiseError("cannot convert portStr " + portStr + " to int32, ignore this slice.", _
                           errorHandle.errorType.warning)
            Else
                addresses.insert(make_pair(hosts(i), port))
            End If
        Next

        If addresses.size() <> hosts.size() Then
            raiseError("duplicate host/port found in inputhost & inputport " + inputhost + ", " + inputport, _
                       errorHandle.errorType.warning)
        End If

        If addresses.size() > 0 Then
            Dim it As [set](Of pair(Of String, Int32)).iterator = Nothing
            it = addresses.begin()
            While it <> addresses.end()
                Dim node As stornode = Nothing
                node = New stornode((+it).first, (+it).second)
                initialStornode(node, (+it).first)
                If (node.holdTime - 1000) > 0 Then
                    node.holdTime -= 1000
                End If
                assert(this.slices.push_back(node), "slices.push_back(node) returns false.")
                it += 1
            End While

            this.enablecache = False

            Dim holdtime As Int64
            holdtime = config.parameter(configNaming.storoom.name, _
                                        configNaming.storoom.distributeOperationHoldtime, _
                                        configNaming.storoom.defaultValue.distributeOperationHoldtime)
            If (holdtime - 1000) > 0 Then
                holdtime -= 1000
            End If
            this.distributeOperationHoldtime = holdtime

            Dim tc As Int64
            tc = config.parameter(configNaming.storoom.name, _
                                  configNaming.storoom.threadcount, _
                                  configNaming.storoom.defaultValue.threadcount)
            If (tc >> 2) > 1 Then   '<=8
                tc >>= 2
            ElseIf (tc >> 1) > 1 Then   '<=4
                tc >>= 1
            End If
            this.threadCount = tc * this.slices.size()

            this.disablelocks()

            this.startImpl()
        Else
            raiseError("no addresses found in inputhost & inputport " + inputhost + ", " + inputport, _
                       errorHandle.errorType.warning)
        End If
    End Sub

    Public Function _display(ByVal this As nodes_redundance2, ByVal displaySeparator As String, _
                             Optional ByVal length As Int64 = 64) As String
        assert(Not this Is Nothing)
        Dim rtn As String = Nothing
        If Not this.slices Is Nothing AndAlso this.slices.size() > 0 Then
            Dim i As Int64
            For i = 0 To this.slices.size() - 1
                Dim s As String = Nothing
                s = convertor.cast(Of stornodebase)(this.slices(i)).display()
                If strlen(s) + strlen(rtn) + strlen(displaySeparator) <= length Then
                    rtn += displaySeparator + s
                End If
            Next

            Return rtn
        Else
            Return Nothing
        End If
    End Function
End Module